home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / tcpip / misc / tnc1stuf.lzh / NET_TNC.ARC / KISSPLUS.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-01-27  |  52.1 KB  |  1,976 lines

  1.     PAGE    60
  2. ; *********************************************************************
  3. ; **  KISS Protocol Program for VADCG TNC+ and            KISS V1.03 **
  4. ; **       VADCG TNC1 with 2732 EPROM mod                            **
  5. ; **              By: Mike Bruski, AJ9X                    08FEB87   **
  6. ; *********************************************************************
  7.  
  8. ;     Change History:
  9. ;       When       Who         What
  10. ;    26JAN87    AJ9X         Initial Version (V1.00)
  11. ;    31JAN87    AJ9X        Removed auto baud rate detection &
  12. ;                interval timer driven by 8253 (V1.01)
  13. ;    07FEB87    AJ9X        Send last character and release cell
  14. ;                on transmitted async. frames (V1.02)
  15. ;    08FEB87    AJ9X        Disabled early end of frame interrupt
  16. ;                from 8273 to prevent transmitter
  17. ;                shutdown prior to sending CRC and
  18. ;                closing flag (V1.03)
  19.     PAGE
  20.  
  21. ;
  22. ;       8250 SIO Controller Equates
  23.  
  24. ;    Registers:
  25.  
  26. RBR    EQU    0        ; RECEIVE BUFFER REGISTER            [R]
  27. THR    EQU    0        ; TRANSMIT HOLDING REGISTER          [W]
  28. DLL    EQU    0        ; DRIVER LATCH (LSB)                 [W]
  29. DLM    EQU    1        ; DRIVER LATCH (MSB)                 [W]
  30. IER    EQU    1        ; INTERRUPT ENABLE REGISTER          [W]
  31. IIR    EQU    2        ; INTERRUPT IDENTIFICATION REGISTER  [R]
  32. LCR    EQU    3        ; LINE CONTROL REGISTER            [R/W]
  33. MCR    EQU    4        ; MODEM CONTROL REGISTER           [R/W]
  34. LSR    EQU    5        ; LINE STATUS REGISTER             [R/W]
  35. MSR    EQU    6        ; MODEM STATUS REGISTER            [R/W]
  36.  
  37. ;    Equates for Interrupt Enable Register
  38.  
  39. ERI    EQU    00000001B    ; ENABLE RECEIVE DATA INTERRUPTS
  40. ETI    EQU    00000010B    ; ENABLE TRANSMIT DATA INTERRUPTS
  41. ELI    EQU    00000100B    ; ENABLE LINE STATUS INTERRUPTS
  42. EMI    EQU    00001000B    ; ENABLE MODEM STATUS INTERRUPTS
  43.  
  44. ;       Equates for Line Status Register
  45.  
  46. DR      EQU     00000001B       ; DATA READY
  47. OE    EQU    00000010B    ; OVERRUN ERROR
  48. PE    EQU    00000100B    ; PARITY ERROR
  49. FE    EQU    00001000B    ; FRAMING ERROR
  50. BI    EQU    00010000B    ; BREAK INTERRUPT
  51. THRE    EQU    00100000B    ; TRANSMIT HOLDING REGISTER EMPTY
  52. TSRE    EQU    01000000B    ; TRANSMIT SHIFT REGISTER EMPTY
  53.  
  54. ;    Equates for Modem Status Register
  55.  
  56. DCTS    EQU    00000001B    ; DELTA CLEAR-TO-SEND
  57. DDSR    EQU    00000010B    ; DELTA DATA-SET-READY
  58. TERI    EQU    00000100B    ; TRAILING EDGE OF RING INDICATOR
  59. DCD    EQU    00001000B    ; DELTA CARRIER DETECT
  60. TCTS    EQU    00010000B    ; TERMINAL CLEAR-TO-SEND
  61. TDSR    EQU    00100000B    ; TERMINAL DATA-SET-READY
  62. TRI    EQU    01000000B    ; TERMINAL RING INDICATOR
  63. TCD    EQU    10000000B    ; TERMINAL CARRIER DETECT
  64.  
  65. ;       Equates for Line Control Register
  66.  
  67. D5      EQU     00000000B       ; WORD LENGTH = 5 BITS
  68. D6    EQU    00000001B    ; WORD LENGTH = 6 BITS
  69. D7    EQU    00000010B    ; WORD LENGTH = 7 BITS
  70. D8    EQU    00000011B    ; WORD LENGTH = 8 BITS
  71. S1    EQU    00000000B    ; STOP BITS = 1
  72. S2    EQU    00000100B    ; STOP BITS = 2
  73. NP    EQU    00000000B    ; NO PARITY
  74. PEN    EQU    00001000B    ; PARITY ENABLE
  75. OP    EQU    00000000B    ; ODD PARITY
  76. EP    EQU    00010000B    ; EVEN PARITY SELECT
  77. STP    EQU    00100000B    ; STICK PARITY
  78. SB    EQU    01000000B    ; SET BREAK
  79. DLA    EQU    10000000B    ; DIVISOR LATCH ACCESS
  80.  
  81. ;    Equates for Modem Control Register
  82.  
  83. ADTR    EQU    00000001B    ; ASYNCHRONOUS DATA-TERMINAL-READY
  84. ARTS    EQU    00000010B    ; ASYNCHRONOUS REQUEST-TO-SEND
  85. OUT1    EQU     00000100B       ; ASYNCHRONOUS CARRIER DETECT (LOOP=RI)
  86. OUT2    EQU     00001000B       ; NO CONNECTION ON VADCG (LOOP=CD)
  87. LOOP    EQU    00010000B    ; LOOPBACK DIAGNOSTIC ENABLE
  88.  
  89. ;    Equates for Interrupt Identification Register
  90.  
  91. AIPM    EQU    00000001B    ; ASYNC INT. PENDING MASK
  92. ;                   INTERRUPT IS PENDING IF NOT SET
  93. IIM    EQU    00000110B    ; INTERRUPT IDENTIFICATION MASK
  94. RLSI    EQU    00000110B    ; RECEIVER LINE STATUS INTERRUPT
  95. RDAI    EQU    00000100B    ; RECEIVED DATA AVAILABLE INTERRUPT
  96. TREI    EQU    00000010B    ; TRANSMIT HOLDING REG. EMPTY INTERRUPT
  97. MSI    EQU    00000000B    ; MODEM STATUS INTERRUPT
  98.     PAGE
  99.  
  100. ;
  101. ;    8273 HDLC Controller Equates
  102.  
  103. ;    Registers:
  104.  
  105. STAT73    EQU    10H        ; STATUS REGISTER                    [R]
  106. CMND73  EQU     10H             ; COMMAND REGISTER                   [W]
  107. PARM73  EQU     11H             ; PARAMETER REGISTER                 [W]
  108. RESL73    EQU    11H        ; RESULTS REGISTER                   [R]
  109. TEST73  EQU     12H             ; TEST REGISTER                      [W]
  110. TXIR73    EQU    12H        ; TRANSMIT INTERRUPT RESULTS REGISTER[R]
  111. RXIR73    EQU    13H        ; RECEIVE INTERRUPT RESULTS REGISTER [R]
  112. TXDR73    EQU    18H        ; TRANSMIT DATA REGISTER             [W]
  113. RXDR73    EQU    20H        ; RECEIVE DATA REGISTER              [R]
  114.  
  115. ;    Equates for STAT73
  116.  
  117. TXIRA    EQU    00000001B    ; TRANSMIT INTERRUPT RESULTS AVAILABLE
  118. RXIRA    EQU    00000010B    ; RECEIVE INTERRUPT RESULTS AVAILABLE
  119. TINTP    EQU    00000100B    ; TRANSMIT INTERRUPT STILL PENDING
  120. RINTP    EQU    00001000B    ; RECEIVE INTERRUPT STILL PENDING
  121. CRBF    EQU    00010000B    ; COMMAND RESULTS BUFFER FULL
  122. CPBF    EQU    00100000B    ; COMMAND PARAMETER BUFFER FULL
  123. CBF    EQU    01000000B    ; COMMAND BUFFER FULL
  124. CBSY    EQU    10000000B    ; COMMAND BUFFER BUSY
  125.  
  126. ;    Equates for TXIR73
  127.  
  128. EXI     EQU     00001100B       ; EARLY TRANSMIT INTERRUPT
  129. FTC    EQU    00001101B    ; FRAME TRANSMISSION COMPLETE
  130. DMAU    EQU     00001110B       ; DMA UNDERRUN (not used)
  131. CTSE    EQU    00001111B    ; CLEAR-TO-SEND ERROR
  132. ATC    EQU    00010000B    ; ABORT TRANSMISSION COMPLETE
  133.  
  134. ;    Equates for RXIR73
  135.  
  136. CRCE    EQU    00000011B    ; CRC ERROR
  137. FAD    EQU    00000100B    ; FRAME ABORT DETECTED
  138. IFD    EQU    00000101B    ; IDLE FLAG DETECTED
  139. EOPD    EQU    00000110B    ; EOP DETECTED (not used)
  140. SFD    EQU    00000111B    ; SHORT FRAME DETECTED (< 32 BITS)
  141. DMAO    EQU    00001000B    ; DMA OVERRUN
  142. MBO    EQU    00001001B    ; MEMORY BUFFER OVERFLOW
  143. CDF    EQU    00001010B    ; CARRIER DETECT FAILURE
  144. RIO    EQU    00001011B    ; RECEIVE INTERRUPT OVERRUN
  145.  
  146. ;    Equates for PORT A (input)
  147.  
  148. MCTS    EQU     00000001B       ; MODEM CLEAR-TO-SEND
  149. MCD     EQU     00000010B       ; MODEM CARRIER DETECT
  150. PA2    EQU    00000100B    ; SPARE PORT INPUT
  151. PA3     EQU     00001000B       ; SPARE PORT INPUT
  152. PA4    EQU    00010000B    ; SPARE PORT INPUT
  153.  
  154. ;    Equates for PORT B (output)
  155.  
  156. MRTS    EQU    00000001B    ; MODEM REQUEST-TO-SEND
  157. PB1    EQU    00000010B    ; SPARE PORT OUTPUT
  158. PB2    EQU    00000100B    ; SPARE PORT OUTPUT
  159. PB3    EQU    00001000B    ; SPARE PORT OUTPUT
  160. PB4    EQU    00010000B    ; SPARE PORT OUTPUT
  161. FD    EQU    00100000B    ; FLAG DETECT
  162.     PAGE
  163.  
  164. ;
  165. ;    8253 Interval Timer Equates (VDS-1 only)
  166.  
  167. ;    Registers:
  168.  
  169. PIT0    EQU     28H             ; COUNTER PORT 0 (8273 BAUD RATE)
  170. PIT1    EQU     29H             ; COUNTER PORT 1 (8085 TRAP)
  171. PIT2    EQU    2AH        ; COUNTER PORT 2
  172. ITCP    EQU     2BH             ; INTERVAL TIMER CONTROL PORT
  173.  
  174. ;    Equates for ITCP (control word)
  175.  
  176. ;    Register selection field
  177. C0    EQU    00000000B    ; COUNTER 0
  178. C1    EQU    01000000B    ; COUNTER 1
  179. C2    EQU    10000000B    ; COUNTER 2
  180.  
  181. ;    Read/Load control field
  182. LC    EQU    00000000B    ; LATCH COUNT
  183. RLL    EQU    00010000B    ; READ/LOAD LSB ONLY
  184. RLM    EQU    00100000B    ; READ/LOAD MSB ONLY
  185. RLB    EQU    00110000B    ; READ/LOAD LSB FIRST, MSB NEXT
  186.  
  187. ;    Mode control field
  188. MD0    EQU    00000000B    ; MODE 0, TIMED INTERRUPT
  189. MD1    EQU    00000010B    ; MODE 1, RETRIGGERABLE ONE SHOT
  190. MD2     EQU     00000100B       ; MODE 2, RATE GENERATOR
  191. MD3     EQU     00000110B       ; MODE 3, SQUARE WAVE GENERATOR
  192. MD4    EQU    00001000B    ; MODE 4, SOFTWARE TRIGGERED STROBE
  193. MD5     EQU     00001010B       ; MODE 5, HARDWARE TRIGGERED STROBE
  194.  
  195. ;    Counter Type field
  196. BIN    EQU    00000000B    ; 16 BIT BINARY
  197. BCD    EQU    00000001B    ;  4 DECADE BCD
  198.  
  199. ;    Equates for PIT0 (Synchronous Baud Rate Values)
  200.  
  201. SBR9600    EQU    4        ; 9600 baud
  202. SBR4800    EQU    8        ; 4800 baud
  203. SBR2400    EQU    16        ; 2400 baud
  204. SBR1200    EQU    32        ; 1200 baud (default)
  205. SBR600    EQU    64        ;  600 baud
  206. SBR300    EQU    128        ;  300 baud
  207.  
  208. ;    Equates for PIT1 (Cyclic Timer) - NOT USING THIS YET
  209. ;       Input = 38.4Khz from pin 4 of U40
  210.  
  211. MS100   EQU     3840            ; 100ms timer value
  212. MS50    EQU     1920            ;  50ms timer value
  213. MS20    EQU    768        ;  20ms timer value
  214. MS10    EQU     384             ;  10ms timer value (default)
  215.  
  216. ;  Use these guys for S/W timing (now for all VADCG & ASHBY)
  217. IC100    EQU    2297        ; Interval count for 100ms
  218. IC10    EQU    230        ; Interval count for 10ms
  219.  
  220. ;    Equates for PIT2 (Random Number Generator)
  221. ;    Input = 38.4Khz from pin 4 of U40
  222.  
  223. SEED    EQU    32767
  224.     PAGE
  225.  
  226. ;
  227. ;    8085 CPU Interrupt Mask Register Equates
  228.  
  229. ACD    EQU    00000001B    ; RST5.5, ASYNC. INTERRUPTS DISABLED
  230. STD    EQU    00000010B    ; RST6.5, SYNC. XMTR INT. DISABLED
  231. SRD    EQU    00000100B    ; RST7.5, SYNC. RCVR INT. DISABLED
  232. MSE     EQU     00001000B       ; INTERRUPT MASK ENABLED
  233.  
  234. ;
  235. ;       Special Character Equates
  236. EOS    EQU    00H
  237. LF    EQU    0AH
  238. CR    EQU    0DH
  239. COMMA    EQU    2CH
  240. PERIOD    EQU    2EH
  241. FEND    EQU    0C0H
  242. FESC    EQU    0DBH
  243. TFEND    EQU    0DCH
  244. TFESC    EQU    0DDH
  245.  
  246. ;
  247. ;    End Action (Event) Flags
  248. SRFC    EQU    00000001B    ; SYNC. RECEIVER FRAME COMPLETION
  249. ARFC    EQU    00000010B    ; ASYNC. RECEIVER FRAME COMPLETION
  250. STFC    EQU    00000100B    ; SYNC. TRANSMITTER FRAME COMPLETION
  251. ATFC    EQU    00001000B    ; ASYNC. TRANSMITTER FRAME COMPLETION
  252. EXTI    EQU    00010000B    ; EXPIRED TIMER
  253. SRDD    EQU     00100000B       ; SYNC. RECEIVER DISCARDING DATA
  254. ARDD    EQU     01000000B       ; ASYNC. RECEIVER DISCARDING DATA
  255.  
  256. ;
  257. ;    Miscellaneous Equates
  258. WDVAL    EQU    220        ; DEFAULT WATCH DOG DELAY FOR 1200 BAUD
  259.     PAGE
  260.  
  261. TRUE    EQU    -1
  262. FALSE    EQU    NOT TRUE
  263. ;
  264. ;    Static Random Access Memory (SRAM) Equates
  265.  
  266. ;    LORAM    HIRAM    CONFIGURATION
  267. ;
  268. ;    1000H    1FFFH  *ASHBY with 2716 ROMs or Standard VADCG
  269. ;    2000H    2FFFH    ASHBY with 2732 ROMs
  270. ;    7000H    7FFFH    VADCG with California memory mods
  271. ;    8000H    8FFFH    VADCG with early AMRAD memory mods
  272. ;    8000H    9FFFH    VADCG with VDS-1 (8K RAM)
  273. ;    8000H    FFFFH    VADCG with VDS-1 (32K RAM)
  274. ;       4000H   4FFFH   VADCG with VADCG 2732 modification
  275.  
  276. TNCPLUS    EQU    TRUE
  277. TNC32   EQU     FALSE
  278.  
  279.     IF TNCPLUS
  280. VECTORS    EQU    0FF00H    ; Restart and interrupt vectors in RAM
  281. MONENT    EQU    0    ; Monitor entry point
  282. LORAM    EQU    0C000H    ; Beginning of RAM
  283. HIRAM    EQU    0DFFFH    ; End of RAM
  284.     ELSE
  285. LORAM    EQU    1000H        ; BEGINNING OF SRAM
  286. HIRAM    EQU    1FFFH        ; END OF SRAM
  287.     ENDIF
  288.     
  289. STACK    EQU    LORAM+64H    ; BEGINNING OF PROGRAM STACK
  290. TICKCNT    EQU    STACK+1        ; TICK COUNT FOR TNC+
  291. EA$FLG    EQU    STACK+2        ; END ACTION FLAGS
  292.  
  293. ;    Interval Timer Variables
  294. PVAL    EQU    EA$FLG+1    ; PERSISTENCE VALUE
  295. SVAL    EQU     PVAL+1          ; SLOT-TIME VALUE
  296. RVAL    EQU     SVAL+1          ; RELAY DELAY VALUE
  297. TVAL    EQU    RVAL+1        ; SQUELCH TAIL DELAY VALUE
  298. TICKS   EQU     TVAL+1          ; TICK COUNTER FOR S/W TIMING
  299. IT$FLG    EQU    TICKS+2        ; 0 = INACTIVE, 1 = ACTIVE
  300. IT$VAL    EQU    IT$FLG+1    ; CURRENT TIMER VALUE
  301. IT$STA    EQU    IT$VAL+2    ; CURRENT TIMER STATE
  302.  
  303. ;    Asynchronous Receiver Variables
  304. AR$HC    EQU    IT$STA+1    ; CURRENT FRAME HEAD
  305. AR$BP    EQU    AR$HC+2        ; CURRENT BUFFER POINTER
  306. AR$FSZ    EQU    AR$BP+2        ; CURRENT FRAME SIZE
  307. AR$FH    EQU    AR$FSZ+2    ; COMPLETED FRAME HEAD
  308. AR$FS    EQU    AR$FH+2        ; COMPLETED FRAME SIZE
  309. AR$STA    EQU    AR$FS+2        ; CURRENT MACHINE STATE
  310.  
  311. ;    Asynchronous Transmitter Variables
  312. AT$BP    EQU    AR$STA+1    ; CURRENT BUFFER POINTER
  313. AT$QS    EQU    AT$BP+2        ; QUEUE SIZE
  314. AT$QR    EQU    AT$QS+1        ; QUEUE READ POINTER
  315. AT$QW    EQU    AT$QR+2        ; QUEUE WRITE POINTER
  316. AT$STA  EQU     AT$QW+2         ; CURRENT MACHINE STATE
  317.  
  318. ;    Synchronous Receiver Variables
  319. SR$HC   EQU     AT$STA+1        ; CURRENT FRAME HEAD
  320. SR$BP    EQU    SR$HC+2        ; CURRENT BUFFER POINTER
  321. SR$FR    EQU    SR$BP+2        ; CURRENT FRAME RESULTS
  322. SR$STA    EQU    SR$FR+1        ; CURRENT MACHINE STATE
  323.  
  324. ;    Synchronous Transmitter Variables
  325. ST$BP    EQU    SR$STA+1    ; CURRENT BUFFER POINTER
  326. ST$FR    EQU    ST$BP+2        ; CURRENT FRAME RESULTS
  327. ST$QS    EQU    ST$FR+1        ; QUEUE SIZE
  328. ST$QR    EQU    ST$QS+1        ; QUEUE READ POINTER
  329. ST$QW    EQU    ST$QR+2        ; QUEUE WRITE POINTER
  330.  
  331. ;    Synchronous Command Buffers
  332. SRACT    EQU    ST$QW+2        ; RECEIVER ACTIVATION COMMAND
  333. STACT    EQU    SRACT+4        ; TRANSMITTER ACTIVATION COMMAND
  334.  
  335. ;    Asynchronous Transmitter Queue
  336. AT$QT    EQU    STACT+4        ; TOP OF QUEUE
  337. AT$QB   EQU     AT$QT+(2*64)    ; BOTTOM OF QUEUE
  338.  
  339. ;    Synchronous Transmitter Queue
  340. ST$QT   EQU     AT$QB+2         ; TOP OF QUEUE
  341. ST$QB    EQU    ST$QT+(4*64)    ; BOTTOM OF QUEUE
  342.  
  343. ;    Buffer area
  344. FL$HC    EQU    ST$QB+4
  345. NCELL    EQU    (HIRAM-FL$HC+2)/128
  346. BAREA    EQU    (HIRAM-NCELL*128)+1 ; BEGINNING OF BUFFER AREA
  347. NLIST    EQU    BAREA-2        ; # OF AVAILABLE CELLS IN FREE LIST
  348.     PAGE
  349.  
  350. BASE    EQU    0
  351.     ORG    BASE        ; PROGRAM ORIGIN
  352.  
  353.     IF NOT TNCPLUS
  354. ;
  355. ;    Here we begin -
  356. ;    A good place to start is with the interrupt vectors
  357.  
  358. ;
  359. ;       RST0 - [H/W AND S/W INTERRUPT]
  360. ;    ENTER HERE ON POWER UP AND WHEN THE RESET
  361. ;       BUTTON IS SMASHED TO INITIALIZE THE H/W
  362. ;    AND MEMORY.  MIGHT ALSO VECTOR HERE IN S/W
  363. ;    IF EVERYTHING IS SO MESSED UP THE TNC CAN'T
  364. ;    FUNCTION CORRECTLY.
  365.  
  366. RST0    EQU    $        ; RESTART (WARM & COLD)
  367.     JMP    INIT
  368.  
  369.     ORG    BASE+08H
  370.  
  371. ;
  372. ;    RST1 - [S/W INTERRUPT]
  373. ;    ENTER HERE TO RETURN FROM AN INTERRUPT.  THE FIRST
  374. ;    ITEM ON THE STACK WILL BE A RETURN ADDRESS TO THE
  375. ;    RST INSTRUCTION WHICH GOT US HERE SO IT GETS WASTED.
  376. ;    NEXT THE PROGRAM STATUS WORD (ACCUMULATOR & FLAGS)
  377. ;    ARE RESTORE, INTERRUPTS ARE RE-ENABLED AND THE REST
  378. ;    IS HISTORY.
  379.  
  380. RST1    EQU     $
  381.     POP    PSW        ; PURGE BOGUS ADDRESS FROM STACK
  382.     POP    PSW        ; RESTORE PROGRAM STATUS WORD
  383.     EI            ; UNGATE INTERRUPTS
  384.     RET            ; RETURN TO POINT OF INTERRUPT
  385.  
  386.     ORG    BASE+10H
  387.  
  388. ;
  389. ;    RST2 - [S/W INTERRUPT]
  390. ;    NO FUNCTION
  391.  
  392. RST2    EQU    $
  393.     RET
  394.  
  395.     ORG    BASE+18H
  396.  
  397. ;
  398. ;    RST3 - [S/W INTERRUPT]
  399. ;    NO FUNCTION
  400.  
  401. RST3    EQU     $
  402.     RET
  403.  
  404.     ORG    BASE+20H
  405.  
  406. ;
  407. ;    RST4 - [S/W INTERRUPT]
  408. ;    NO FUNCTION
  409.  
  410. RST4    EQU    $
  411.     RET
  412.  
  413.     ORG    BASE+24H
  414.  
  415. ;
  416. ;    TRAP - [NON MASKABLE H/W INTERRUPT]
  417. ;    NOT USED
  418.  
  419. TRAP    EQU    $
  420.     EI
  421.     RET
  422.  
  423.     ORG    BASE+28H
  424.  
  425. ;
  426. ;    RST5 - [S/W INTERRUPT]
  427. ;    NO FUNCTION
  428.  
  429. RST5    EQU    $
  430.     RET
  431.  
  432.     ORG    BASE+2CH
  433.  
  434. ;
  435. ;    RST5.5 - [MASKABLE H/W INTERRUPT]
  436. ;    VECTOR HERE WHEN A SIGNAL IS DETECTED ON PIN 9 OF
  437. ;    THE 8085.  THE 8250 WILL ASSERT THIS PIN WHEN ONE
  438. ;    OF THE FOLLOWING OCCURS; TRANSMIT BUFFER EMPTY,
  439. ;    RECEIVE CHARACTER AVAILABLE, RECEIVER OVERRUN,
  440. ;    RECEIVER PARITY ERROR, RECEIVER FRAMING ERROR,
  441. ;    BREAK INTERRUPT, DELTA CTS, DELTA DSR, RING INDICATE
  442. ;       OR RECEIVE LINE SIGNAL DETECT.
  443.  
  444. RST55    EQU    $
  445.     JMP    AIRC    ; GOTO ASYNC. INTERRUPT RESPONSE CODE
  446.  
  447.     ORG    BASE+30H
  448.  
  449. ;
  450. ;    RST6 - [S/W INTERRUPT]
  451. ;    NO FUNCTION
  452.  
  453. RST6    EQU    $
  454.     RET
  455.  
  456.     ORG    BASE+34H
  457.  
  458. ;
  459. ;    RST6.5 - [MASKABLE H/W INTERRUPT]
  460. ;    VECTOR HERE WHEN A SIGNAL IS DETECTED ON PIN 8 OF
  461. ;    THE 8085.  THE 8273 WILL ASSERT THIS PIN WHEN THE
  462. ;    SYNCHRONOUS TRANSMITTER REQUIRES SERVICE.
  463.  
  464. RST65   EQU     $
  465.     JMP     STIRC   ; GOTO SYNC. XMTR INTERRUPT RESPONSE CODE
  466.  
  467.     ORG    BASE+38H
  468.  
  469. ;
  470. ;    RST7 - [S/W INTERRUPT]
  471. ;    NO FUNCTION
  472.  
  473. RST7    EQU    $
  474.     RET
  475.  
  476.     ORG    BASE+3CH
  477.  
  478. ;
  479. ;    RST7.5 - [MASKABLE H/W INTERRUPT]
  480. ;    VECTOR HERE WHEN A SIGNAL IS DETECTED ON PIN 7 OF
  481. ;    THE 8085.  THE 8273 WILL ASSERT THIS PIN WHEN THE
  482. ;    SYNCHRONOUS RECEIVER REQUIRES SERVICE.
  483.  
  484. RST75   EQU     $
  485.     JMP     SRIRC   ; GOTO SYNC. RCVR INTERRUPT RESPONSE CODE
  486.  
  487.     ENDIF
  488.  
  489.     PAGE
  490. ;
  491. ;    Initialize Hardware
  492. ;    Branch here for critical S/W errors or H/W reset
  493.  
  494. ;    Begin by reseting the 8250, 8253, and 8273
  495. INIT    EQU    $
  496.     DI            ; GATE INTERRUPTS
  497.     LXI    SP,STACK    ; SET STACK POINTER
  498.     CALL    INIT73        ; Initialize 8273
  499.     XRA    A        ; A <-- 0              [ 4 tcy]
  500.     OUT    MCR        ; DROP 8250 DTR & RTS  [10 tcy]
  501.     OUT    IER        ; KILL 8250 INTERRUPTS [10 tcy]
  502.     IN    RBR        ; FLUSH THE 8250 INPUT REGISTER
  503.     IN    RBR
  504.  
  505. ;       H/W is now in an acceptable state, continue
  506.  
  507. ;    Now clear SRAM
  508.     LXI    D,HIRAM        ; DE <-- HIGH SRAM ADDRESS
  509.     LXI    H,LORAM        ; HL <-- LOW SRAM ADDRESS
  510.  
  511. INIT1    EQU    $
  512.     MVI    M,0        ; CLEAR NEXT LOCATION
  513.     INX    H        ; INCREMENT POINTER
  514.     MOV    A,D        ; A <-- MSB OF HIGH ADDRESS
  515.     CMP    H
  516.     JNZ    INIT1        ; IF (D <> H) GOTO INIT1
  517.     MOV    A,E        ; A <-- LSB OF HIGH ADDRESS
  518.     CMP    L
  519.     JNZ    INIT1        ; IF (E <> L) GOTO INIT1
  520.     MVI    M,0        ; ZERO LAST RAM LOCATION
  521.  
  522. ;    Initialize linked list of free cells
  523.     MVI    A,NCELL        ; A <-- # OF CELLS
  524.         STA    NLIST        ; SAVE IN SRAM
  525.     MOV    B,A        ; NOW MOVE CELL COUNT TO B
  526.     LXI     D,BAREA         ; DE <-- ADDRESS OF BUFFER AREA
  527.     DCR     B               ; SO THAT LAST CELL IS 0
  528. INIT2    EQU    $
  529.     LXI    H,128        ; HL <-- CELL SIZE
  530.  
  531.     IF    TNC32
  532.     MOV    A,B
  533.     ANI    0FH
  534.     CPI    8
  535.     JZ    INIT2A
  536.     LXI    H,0C80H
  537. INIT2A:
  538.     ENDIF
  539.  
  540.     DAD    D        ; HL <-- ADDRESS OF NEXT CELL
  541.     XCHG            ; DE <-- NEXT, HL <-- CURRENT
  542.     MOV    M,E        ; CURRENT GETS LSB OF NEXT
  543.     INX    H
  544.     MOV    M,D        ; FOLLOWED BY MSB OF NEXT
  545.     DCR    B        ; B <-- B-1
  546.     JNZ    INIT2        ; IF (B <> 0) GOTO INIT2
  547.  
  548. ;       Initialize state variables
  549.     MVI    A,7
  550.     STA    AR$STA
  551.     MVI    A,0FFH
  552.     STA    AT$STA
  553.  
  554. ;    Initialize queue variables
  555.     LXI    H,AT$QT
  556.     SHLD    AT$QR
  557.     SHLD    AT$QW
  558.     LXI    H,ST$QT
  559.     SHLD    ST$QR
  560.     SHLD    ST$QW
  561.  
  562. ;    Initialize miscellaneous variables
  563.     LXI    H,0C002H    ; GENERAL RECEIVE COMMAND (8273)
  564.     SHLD    SRACT
  565.     LXI    H,330        ;*;; MAXIMUM ALLOWABLE PACKET LENGTH
  566.     SHLD    SRACT+2
  567.     LXI    H,0C802H    ; TRANSMIT FRAME COMMAND (8273)
  568.     SHLD    STACT
  569.     LXI     H,BAREA         ; H <-- ADDRESS OF FREE CELL AREA
  570.     SHLD    FL$HC        ; ESTABLISH FREE LIST HEAD CELL
  571.     LXI    H,MS10        ; H <-- CONSTANT FOR 10MS S/W TIMING
  572.     SHLD    TICKS        ; PRELOAD S/W COUNT VARIABLE
  573.     MVI    A,2        ; DEFAULT SQUELCH TAIL DELAY (20ms)
  574.     STA    TVAL
  575.     MVI    A,5        ; DEFAULT SLOT-TIME DELAY (50ms)
  576.     STA    SVAL
  577.     MVI    A,30        ; DEFAULT RELAY DELAY (300ms)
  578.     STA    RVAL
  579.     MVI    A,128        ; DEFAULT PERSISTENCE VALUE (0.5)
  580.     STA    PVAL
  581.  
  582.     IF TNCPLUS
  583. ; Install interrupt vectors
  584.     MVI    A,0C3H
  585.     STA    VECTORS+2CH    ; 8250 interrupt
  586.     LXI    H,AIRC
  587.     SHLD    VECTORS+2DH
  588.  
  589.     STA     VECTORS+34H     ; 8273 transmit interrupt
  590.     LXI     H,STIRC
  591.     SHLD    VECTORS+35H
  592.  
  593.     STA    VECTORS+3CH    ; 8273 receive interrupt
  594.     LXI    H,SRIRC
  595.     SHLD    VECTORS+3DH
  596.  
  597.     STA    VECTORS+38H    ; 8255 interrupt
  598.     LXI    H,MONENT
  599.     SHLD    VECTORS+39H
  600.  
  601.     ELSE
  602.  
  603. ;    Establish baud rate for asynchronous port
  604.     LXI    H,32        ; CONSTANT FOR 4800 BAUD
  605.     MVI    A,DLA        ; A <-- DIVISOR LATCH ACCESS FLAG
  606.     OUT    LCR        ; WRITE LINE CONTROL REGISTER
  607.     MOV    A,L        ; A <-- LSB OF BAUD RATE CONSTANT
  608.     OUT    DLL        ; WRITE DIVISOR LATCH LSB
  609.     MOV    A,H        ; A <-- MSB OF SAME
  610.     OUT    DLM        ; WRITE DIVISOR LATCH MSB
  611.     MVI    A,NP+D8+S2    ; NO PARITY, 8 DATA BITS, 2 STOP BITS
  612.     OUT    LCR        ; WRITE LINE CONTROL REGISTER
  613.     ENDIF
  614.  
  615. ;**********************************************************************
  616. ;    The following code segment is for VDS-1 users only!!!
  617. ;       Erase ';*;' in columns 1 thru 3 to assemble this segment.
  618. ;    Establish baud rate for synchronous port
  619. ;*;    MVI    A,C0+RLB+MD3+BIN ; 8253 MODE CONTROL WORD
  620. ;*;    OUT    ITCP        ; WRITE INTERVAL TIMER CONTROL PORT
  621. ;*;    LXI    H,SBR1200    ; CONSTANT FOR 1200 BAUD
  622. ;*;    MOV    A,L        ; A <-- LSB
  623. ;*;    OUT    PIT0        ; WRITE
  624. ;*;    MOV    A,H        ; A <-- MSB
  625. ;*;    OUT    PIT0        ; WRITE
  626.  
  627. ;    Activate the random number generator.
  628. ;*;    MVI    A,C2+RLB+MD3+BIN ; MODE CONTROL WORD
  629. ;*;    OUT    ITCP        ; WRITE
  630. ;*;    LXI    H,SEED        ; COUNTER VALUE
  631. ;*;    MOV    A,L        ; A <-- LSB
  632. ;*;    OUT    PIT2        ; WRITE
  633. ;*;    MOV    A,H        ; A <-- MSB
  634. ;*;    OUT    PIT2        ; WRITE
  635. ;**********************************************************************
  636.  
  637. ;    Asynchronous controller activation
  638. ;    RST5.5 to CPU is enabled first
  639.     MVI    A,ERI+ELI+EMI    ; RECEIVE AND LINE STATUS ENABLE
  640.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  641.     MVI    A,ADTR+ARTS+OUT1 ; DTR, RTS, & CD FOR HOST
  642.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  643.  
  644.     CALL    GCELL        ; GET A FREE CELL
  645.     XCHG            ; HL <-- CELL POINTER
  646.     SHLD    SR$BP        ; ESTABLISH NEW POINTERS
  647.     SHLD    SR$HC
  648.     MVI    M,0        ; RESET FORWARD POINTER
  649.     INX    H        ; ADVANCE POINTER
  650.     MVI    M,0
  651.     MVI    A,MSE        ; UNGATE RST5.5,RST6.5, & RST7.5
  652.     DB    30H        ; 8085 SIM INSTRUCTION
  653.     LXI    H,SRACT        ; SYNC. RECEIVER ACTIVATION COMMAND
  654.     CALL    SCMDOT
  655.  
  656. ;    LIGHTS! CAMERA! ACTION!
  657.     EI
  658.     PAGE
  659.  
  660. ;    TNC Executive Routine
  661.  
  662. EXEC    EQU    $
  663.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  664.     ANA    A
  665.     JNZ    EXEC2        ; IF (FLAGS SET) GOTO EXEC2
  666.     LDA    IT$FLG        ; A <-- TIMER CONTROL FLAG
  667.     ORA    A
  668.     JNZ    EXEC1        ; IF (TIMER ACTIVE) GOTO EXEC1
  669.     LXI    H,RPA        ; HL <-- READ PORT A COMMAND
  670.     CALL    SCMDOT        ; ISSUE COMMAND
  671.     CALL    SRSLIN        ; READ RESULTS
  672.     ANI    MCD        ; MASK MODEM CARRIER DETECT
  673.     JNZ    EXEC        ; IF (CHANNEL BUSY) GOTO EXEC
  674.     LDA    ST$QS        ; A <-- SYNC. XMTR QUEUE SIZE
  675.     ORA    A
  676.     JZ    EXEC        ; IF (EMPTY QUEUE) GOTO EXEC
  677.  
  678. ;**********************************************************************
  679. ;    The following code segment is for VDS-1 users only!!!
  680. ;       Remove ';*; in column 1 thru 3 to assemble this segment.
  681. ;  ASHBY and non-VDS VADCGs are rendered totally non-persistent
  682. ;*;    MVI    A,C2+RLL    ; READ CONTROL WORD
  683. ;*;    OUT    ITCP        ; WRITE INTERVAL TIMER CONTROL PORT
  684. ;*;    IN    PIT2        ; READ LSB OF TIMER (OUR RANDOM #)
  685. ;*;    MOV    B,A        ; COPY TO B FOR NOW
  686. ;*;    LDA    PVAL        ; A <-- PERSISTENCE VALUE
  687. ;*;    SUB    B
  688. ;*;    JNC    A5$S0A        ; IF (RANDOM < PVAL) GOTO A5$S0A
  689. ;**********************************************************************
  690.     IF    TNCPLUS
  691.     LDA    TICKCNT        ; Get TNC+ 75Hz. timer count
  692.     MOV    B,A        ; Copy to B for now
  693.     LDA    PVAL        ; A<-- Persistence value
  694.     SUB    B
  695.     JNC    A5$S0A        ; If (Random < Pval) go to A5$S0A
  696.     ENDIF
  697.  
  698.  
  699.  
  700.     LDA    SVAL        ; A <-- SLOT-TIME VALUE
  701.     MOV    L,A        ; COPY TO L
  702.     XRA    A
  703.     MOV    H,A        ; EXTEND 16 BITS
  704.     SHLD    IT$VAL        ; ESTABLISH TIMER VALUE
  705.     STA    IT$STA        ; RECORD NEW STATE
  706.     INR    A
  707.     STA    IT$FLG        ; ACTIVATE TIMER
  708.     JMP    EXEC
  709.  
  710. ;    Active timer processing
  711. EXEC1    EQU    $
  712.     LHLD    TICKS        ; HL <-- S/W TIMER COUNT
  713.     DCX    H        ; DECREMENT
  714.     SHLD    TICKS        ; RECORD NEW COUNT
  715.     MOV    A,L        ; A <-- LSB OF COUNT
  716.     ORA    H        ; MSB
  717.     JNZ    EXEC        ; IF (NOT 0) GOTO EXEC
  718.     LXI    H,MS10        ; 10ms TIMER CONSTANT
  719.     SHLD    TICKS        ; RELOAD COUNT
  720.     LHLD    IT$VAL        ; HL <-- INTERVAL TIMER VALUE
  721.     DCX    H        ; DECREMENT TIMER
  722.     SHLD    IT$VAL        ; RECORD IT
  723.     MOV    A,L
  724.     ORA    H
  725.     JNZ    EXEC        ; IF (NOT EXPIRED) GOTO EXEC
  726.     STA    IT$FLG        ; DEACTIVATE TIMER
  727.     DI            ; GATE INTERRUPTS MOMENTARILY
  728.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  729.     ORI    EXTI        ; FLAG EXPIRED TIMER
  730.     STA    EA$FLG        ; RECORD FLAGS
  731.     EI            ; UNGATE
  732.     JMP    EXEC        ; BACK TO TOP
  733.  
  734. ;    End action processing
  735. EXEC2    EQU    $
  736.     RAR
  737.     JC    EX$A1        ; IF (SRFC) GOTO EX$A1
  738.     RAR
  739.     JC    EX$A2        ; IF (ARFC) GOTO EX$A2
  740.     RAR
  741.     JC    EX$A3        ; IF (STFC) GOTO EX$A3
  742.     RAR
  743.     JC    EX$A4        ; IF (ATFC) GOTO EX$A4
  744.     RAR
  745.     JC    EX$A5        ; IF (EXPIRED TIMER) GOTO EX$A5
  746.     RAR
  747.     JC    EX$A6        ; IF (SRDD) GOTO EX$A6
  748.     RAR
  749.     JC    EX$A7        ; IF (ARDD) GOTO EX$A7
  750.     JMP    EXEC        ; CONTINUE
  751.  
  752.  
  753.  
  754.  
  755.  
  756. ;    Here for synchronous receiver frame completion
  757. EX$A1    EQU    $
  758.     LHLD    SR$HC        ; HL <-- FRAME HEAD
  759.     PUSH    H        ; PRESERVE HL
  760.     DI            ; GATE INTERRUPTS MOMENTARILY
  761.     CALL    GCELL        ; GET A FREE CELL
  762.     EI            ; UNGATE
  763.     JZ    EX$A11        ; IF (BUFFERS FULL) GOTO EX$A11
  764.     XCHG            ; HL <-- CELL POINTER
  765.     SHLD    SR$BP        ; ESTABLISH NEW POINTERS
  766.     SHLD    SR$HC
  767.     MVI    M,0        ; RESET FORWARD POINTER
  768.     INX    H        ; ADVANCE POINTER
  769.     MVI    M,0
  770.     LXI    H,SRACT        ; HL <-- SYNC. RCVR ACTIVATION COMMAND
  771.     CALL    SCMDOT        ; ISSUE COMMAND
  772. EX$A11    EQU    $
  773.     MVI    B,0FFH-SRFC    ; B <-- FLAG MASK
  774.     DI            ; GATE INTERRUPTS MOMENTARILY
  775.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  776.     ANA    B        ; MASK OUT SRFC
  777.     STA    EA$FLG        ; WRITE FLAGS
  778.     EI            ; UNGATE
  779.     POP    H        ; RESTORE FRAME HEAD
  780.     LDA    SR$FR        ; A <-- FRAME RESULTS
  781.     CPI    0E0H        ; EXPECTED RESULTS
  782.     JNZ    EX$A12        ; IF (BAD FRAME) GOTO EX$A12
  783.     CALL    LATQ        ; ELSE LINK FRAME TO ASYNC. XMIT QUEUE
  784.     JMP    EXEC
  785. EX$A12    EQU    $
  786.     CALL    FCHN        ; RELEASE BAD FRAME
  787.     JMP    EXEC
  788.  
  789.  
  790.  
  791.  
  792.  
  793. ;    Here for asynchronous receiver frame completion
  794. EX$A2    EQU    $
  795.     MVI    B,0FFH-ARFC    ; B <-- FLAG MASK
  796.     DI            ; GATE INTERRUPTS MOMENTARILY
  797.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  798.     ANA    B        ; MASK OUT ARFC
  799.     STA    EA$FLG        ; WRITE FLAGS
  800.     EI            ; UNGATE
  801.     LHLD    AR$FS        ; HL <-- FRAME SIZE
  802.     MOV    B,H        ; COPY TO BC
  803.     MOV    C,L
  804.     LHLD    AR$FH        ; HL <-- FRAME HEAD
  805.     CALL    LSTQ        ; LINK FRAME TO SYNC. XMIT QUEUE
  806.     MVI    A,ADTR+ARTS+OUT1 ; DTR, RTS, AND CD FOR HOST
  807.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  808.     JMP    EXEC
  809.  
  810.  
  811.  
  812.  
  813.  
  814. ;    Here for synchronous transmitter frame completion
  815. EX$A3    EQU    $
  816.     MVI    B,0FFH-STFC    ; B <-- FLAG MASK
  817.     DI            ; GATE INTERRUPTS MOMENTARILY
  818.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  819.     ANA    B        ; MASK OUT STFC
  820.     STA    EA$FLG        ; WRITE FLAGS
  821.     EI            ; UNGATE
  822.     LDA    ST$QS        ; A <-- QUEUE SIZE
  823.     ORA    A
  824.     JZ    EX$A32        ; IF (EMPTY QUEUE) GOTO EX$A32
  825.     DCR    A        ; ELSE DECREMENT COUNT
  826.     STA    ST$QS        ; WRITE NEW COUNT
  827.     LHLD    ST$QR        ; HL <-- QUEUE READ POINTER
  828.     LXI    D,-ST$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  829.     PUSH    H
  830.     DAD    D
  831.     POP    H        ; RESTORE READ POINTER
  832.     JNC    EX$A31        ; IF (NOT BOTTOM) GOTO EX$A31
  833.     LXI    H,ST$QT        ; HL <-- QUEUE TOP ADDRESS
  834. EX$A31    EQU    $
  835.     MOV    C,M        ; LSB OF FRAME SIZE
  836.     INX    H        ; ADVANCE POINTER
  837.     MOV    B,M        ; MSB OF FRAME SIZE
  838.     INX    H
  839.     MOV    E,M        ; LSB OF FRAME HEAD
  840.     INX    H
  841.     MOV    D,M        ; MSB OF FRAME HEAD
  842.     INX    H
  843.     SHLD    ST$QR        ; RECORD NEW POINTER
  844.     XCHG            ; HL <-- FRAME HEAD
  845.     SHLD    ST$BP        ; RECORD IT
  846.     LXI    H,STACT+2    ; HL <-- SYNC. XMTR PARAMETER POINTER
  847.     MOV    M,C        ; COPY LSB OF FRAME SIZE
  848.     INX    H        ; ADVANCE POINTER
  849.     MOV    M,B        ; COPY MSB OF FRAME SIZE
  850.     LXI    H,STACT        ; HL <-- SYNC. XMTR ACTIVATION COMMAND
  851.     CALL    SCMDOT        ; ISSUE COMMAND
  852. ;  SET WATCHDOG TIMER HERE (LETS GO FOR A DEFAULT VALUE INITIALLY)
  853.     LXI    H,WDVAL        ; HL <-- DEFAULT WATCHDOG TIMER
  854.     SHLD    IT$VAL        ; RECORD IT
  855.     MVI    A,1
  856.     STA    IT$FLG        ; ENABLE TIMER
  857.     INR    A        ; NEW STATE
  858.     STA    IT$STA        ; RECORD IT
  859.     JMP    EXEC
  860. ;    Queue empty, disable synchronous transmitter (deactivate RTS)
  861. EX$A32    EQU    $
  862.     LXI    H,DARTS        ; HL <-- DEACTIVATE RTS COMMAND
  863.     CALL    SCMDOT        ; ISSUE COMMAND
  864.     LDA    TVAL        ; A <-- SQUELCH TAIL TIMER VALUE
  865.     MOV    L,A        ; COPY VALUE TO L
  866.     XRA    A
  867.     MOV    H,A        ; EXTEND 16 BITS
  868.     SHLD    IT$VAL        ; RECORD IT
  869.     INR    A        ; A <-- 1
  870.     STA    IT$FLG        ; ACTIVATE TIMER
  871.     MVI    A,3        ; NEW STATE
  872.     STA    IT$STA        ; RECORD IT
  873.     JMP    EXEC
  874.  
  875.  
  876.  
  877.  
  878.  
  879. ;    Here for asynchronous transmitter frame completion
  880. EX$A4    EQU    $
  881.     MVI    B,0FFH-ATFC    ; B <-- FLAG MASK
  882.     DI            ; GATE INTERRUPTS MOMENTARILY
  883.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  884.     ANA    B        ; MASK OUT ATFC
  885.     STA    EA$FLG        ; WRITE FLAGS
  886.     EI            ; UNGATE
  887.     LDA    AT$QS        ; A <-- QUEUE SIZE
  888.     ORA    A
  889.     JZ    EXEC        ; IF (EMPTY QUEUE) GOTO EXEC
  890.     DCR    A        ; ELSE DECREMENT COUNT
  891.     STA    AT$QS        ; WRITE NEW COUNT
  892.     LHLD    AT$QR        ; HL <-- QUEUE READ POINTER
  893.     LXI    D,-AT$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  894.     PUSH    H        ; PRESERVE HL
  895.     DAD    D
  896.     POP    H        ; RESTORE QUEUE POINTER
  897.     JNC    EX$A41        ; IF (NOT BOTTOM) GOTO EX$A41
  898.     LXI    H,AT$QT        ; HL <-- QUEUE TOP ADDRESS
  899. EX$A41    EQU    $
  900.     MOV    E,M        ; LSB OF FRAME HEAD
  901.     INX    H
  902.     MOV    D,M        ; MSB OF FRAME HEAD
  903.     INX    H
  904.     SHLD    AT$QR        ; RECORD NEW POINTER
  905.     XCHG            ; HL <-- FRAME HEAD
  906.     CALL    LATQ3        ; SEND FEND
  907.     JMP    EXEC
  908.  
  909.  
  910.  
  911.  
  912.  
  913. ;    Here for timer expiration
  914. EX$A5    EQU    $
  915.     MVI    B,0FFH-EXTI    ; B <-- FLAG MASK
  916.     DI            ; GATE INTERRUPTS MOMENTARILY
  917.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  918.     ANA    B        ; MASK OUT EXTI
  919.     STA    EA$FLG        ; WRITE FLAGS
  920.     EI            ; UNGATE
  921.     LDA    IT$STA        ; A <-- STATE OF INTERVAL TIMER
  922.     ORA    A
  923.     JZ    A5$S0        ; IF (SLOT-TIME DELAY) GOTO A5$S0
  924.     DCR    A
  925.     JZ    A5$S1        ; IF (RELAY DELAY) GOTO A5$S1
  926.     DCR    A
  927.     JZ    A5$S2        ; IF (WATCH DOG) GOTO A5$S2
  928.     DCR    A
  929.     JZ    A5$S3        ; IF (SQUELCH DELAY) GOTO A5$S3
  930.     JMP    EXEC        ; IGNORE INVALID STATES
  931.  
  932. ;    Slot-time is expired, if channel not busy, activate RTS
  933. A5$S0    EQU    $
  934.     LXI    H,RPA        ; HL <-- READ PORT A COMMAND
  935.     CALL    SCMDOT        ; ISSUE COMMAND
  936.     CALL    SRSLIN        ; READ RESULTS
  937.     ANI    MCD        ; MASK MODEM CARRIER DETECT
  938.     JNZ    EXEC        ; IF (CHANNEL BUSY) GOTO EXEC
  939. A5$S0A    EQU    $
  940.     LXI    H,SRDIS        ; HL <-- SYNC. RCVR DISABLE COMMAND
  941.     CALL    SCMDOT        ; ISSUE COMMAND
  942.     LXI    H,STRTS        ; HL <-- SYNC. XMTR RTS ENABLE COMMAND
  943.     CALL    SCMDOT        ; ISSUE COMMAND
  944.     LDA    RVAL        ; A <-- RELAY DELAY VALUE
  945.     MOV    L,A        ; COPY TO L
  946.     XRA    A
  947.     MOV    H,A        ; EXTEND 16 BITS
  948.     SHLD    IT$VAL        ; SET DELAY VALUE
  949.     INR    A        ; A <-- 1
  950.     STA    IT$FLG        ; ACTIVATE TIMER
  951.     STA    IT$STA        ; RECORD NEW STATE
  952.     LXI    H,ST$QS        ; HL <-- QUEUE SIZE POINTER
  953.     DCR    M        ; DECREMENT COUNT
  954.     LHLD    ST$QR        ; HL <-- QUEUE READ POINTER
  955.     LXI    D,-ST$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  956.     PUSH    H
  957.     DAD    D
  958.     POP    H
  959.     JNC    A5$S0B        ; IF (NOT BOTTOM) GOTO A5$S0B
  960.     LXI    H,ST$QT        ; HL <-- QUEUE TOP ADDRESS
  961. A5$S0B    EQU    $
  962.     MOV    A,M        ; LSB OF FRAME SIZE
  963.     STA    STACT+2
  964.     INX    H        ; ADVANCE POINTER
  965.     MOV    A,M        ; MSB OF FRAME SIZE
  966.     STA    STACT+3
  967.     INX    H
  968.     MOV    E,M        ; LSB OF FRAME HEAD
  969.     INX    H
  970.     MOV    D,M        ; MSB OF FRAME HEAD
  971.     INX    H
  972.     SHLD    ST$QR        ; WRITE NEW POINTER
  973.     XCHG
  974.     SHLD    ST$BP        ; ESTABLISH NEW FRAME POINTER
  975.     JMP    EXEC
  976.  
  977. ;    Relay delay time expired, start data transmission
  978. A5$S1    EQU    $
  979.     LXI    H,STACT        ; HL <-- SYNC. XMTR ACTIVATION COMMAND
  980.     CALL    SCMDOT        ; ISSUE COMMAND
  981.     LXI    H,WDVAL        ; HL <-- WATCHDOG TIMER VALUE
  982.     SHLD    IT$VAL        ; RECORD IT
  983.     MVI    A,1
  984.     STA    IT$FLG        ; ACTIVATE TIMER
  985.     INR    A        ; NEW STATE
  986.     STA    IT$STA        ; RECORD IT
  987.     JMP    EXEC
  988.  
  989. ;    Watchdog timer expiration, kill the transmitter
  990. A5$S2    EQU    $
  991.     LXI    H,DARTS        ; HL <-- DEACTIVATE RTS COMMAND
  992.     CALL    SCMDOT        ; ISSUE COMMAND
  993.     JMP    INIT
  994.  
  995. ;    Squelch delay time expired, re-activate the sync. receiver
  996. A5$S3    EQU    $
  997.     LXI    H,SRACT        ; HL <-- SYNC. RCVR ACTIVATION COMMAND
  998.     CALL    SCMDOT        ; ISSUE COMMAND
  999.     JMP    EXEC
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005. ;    Here when synchronous receiver is discarding a frame
  1006. ;    because there are no available free cells.
  1007. EX$A6    EQU    $
  1008.     MVI    B,0FFH-SRDD    ; B <-- FLAG MASK
  1009.     DI            ; GATE INTERRUPTS MOMENTARILY
  1010.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1011.     ANA    B        ; MASK OUT SRDD
  1012.     STA    EA$FLG        ; WRITE FLAGS
  1013.     EI            ; UNGATE
  1014.     LHLD    SR$HC        ; HL <-- FRAME HEAD
  1015.     CALL    FCHN        ; FREE THIS CHAIN
  1016.     LXI    H,SRDIS        ; HL <-- SYNC. RCVR DISABLE COMMAND
  1017.     CALL    SCMDOT        ; ISSUE COMMAND
  1018.     DI            ; GATE INTERRUPTS MOMENTARILY
  1019.     CALL    GCELL        ; GET A FREE CELL
  1020.     EI            ; UNGATE
  1021.     XCHG            ; HL <-- CELL POINTER
  1022.     SHLD    SR$BP        ; ESTABLISH NEW BUFFER POINTERS
  1023.     SHLD    SR$HC
  1024.     MVI    M,0        ; RESET FORWARD POINTER
  1025.     INX    H        ; ADVANCE POINTER
  1026.     MVI    M,0
  1027.     LXI    H,SRACT        ; HL <-- SYNC. RCVR ACTIVATION COMMAND
  1028.     CALL    SCMDOT        ; ISSUE COMMAND
  1029.     XRA    A        ; NEW STATE (RECORDING DATA)
  1030.     STA    SR$STA        ; RECORD IT
  1031.     JMP    EXEC
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037. ;    Here when asynchronous receiver is discarding a frame
  1038. ;    because there are no available free cells.
  1039. EX$A7    EQU    $
  1040.     MVI    B,0FFH-ARDD    ; B <-- FLAG MASK
  1041.     DI            ; GATE INTERRUPTS MOMENTARILY
  1042.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1043.     ANA    B        ; MASK OUT ARDD
  1044.     STA    EA$FLG        ; WRITE FLAGS
  1045.     EI            ; UNGATE
  1046.     LHLD    AR$HC        ; HL <-- FRAME HEAD
  1047.     CALL    FCHN        ; FREE THIS CHAIN
  1048.     MVI    A,ADTR+ARTS+OUT1 ; DTR, RTS, AND CD FOR HOST
  1049.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  1050.     JMP    EXEC
  1051.     PAGE
  1052.  
  1053. ;    Queue management routines for synchronous & asynchronous output
  1054.  
  1055. ;    Link a frame to the synchronous transmit queue
  1056. LSTQ    EQU    $
  1057.     XCHG            ; DE <-- ADDRESS OF FRAME
  1058.     LHLD    ST$QW        ; HL <-- QUEUE WRITE POINTER
  1059.     MOV    M,C        ; LSB OF FRAME SIZE
  1060.     INX    H        ; ADVANCE POINTER
  1061.     MOV    M,B        ; MSB OF FRAME SIZE
  1062.     INX    H
  1063.     MOV    M,E        ; LSB OF FRAME HEAD
  1064.     INX    H
  1065.     MOV    M,D        ; MSB OF FRAME HEAD
  1066.     INX    H        ; HL <-- NEXT QUEUE ENTRY
  1067.     LXI    D,-ST$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  1068.     PUSH    H        ; PRESERVE HL
  1069.     DAD    D
  1070.     POP    H        ; RESTORE QUEUE POINTER
  1071.     JNC    LSTQ1        ; IF (NOT BOTTOM) GOTO LSTQ1
  1072.     LXI    H,ST$QT        ; HL <-- QUEUE TOP ADDRESS
  1073. LSTQ1    EQU    $
  1074.     SHLD    ST$QW        ; WRITE NEW QUEUE POINTER
  1075.     LXI    H,ST$QS        ; HL <-- QUEUE SIZE POINTER
  1076.     INR    M        ; INCREMENT QUEUE SIZE
  1077.     RET
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083. ;    Link a frame to the asynchronous transmit queue
  1084. LATQ    EQU    $
  1085.     LDA    AT$QS        ; A <-- QUEUE SIZE
  1086.     ORA    A
  1087.     JNZ    LATQ1        ; IF (QUEUED FRAMES) GOTO LATQ1
  1088.     LDA    AT$STA        ; A <-- STATE OF ASYNC. TRANSMITTER
  1089.     CPI    0FFH
  1090.     JZ    LATQ3        ; IF (XMTR INACTIVE) GOTO LATQ3
  1091. LATQ1    EQU    $
  1092.     XCHG            ; DE <-- ADDRESS OF FRAME
  1093.     LHLD    AT$QW        ; HL <-- QUEUE WRITE POINTER
  1094.     MOV    M,E        ; LSB OF FRAME HEAD
  1095.     INX    H        ; ADVANCE POINTER
  1096.     MOV    M,D        ; MSB OF FRAME HEAD
  1097.     INX    H        ; HL <-- NEXT QUEUE ENTRY
  1098.     LXI    D,-AT$QB    ; DE <-- QUEUE BOTTOM ADDRESS
  1099.     PUSH    H        ; PRESERVE HL
  1100.     DAD    D
  1101.     POP    H        ; RESTORE QUEUE POINTER
  1102.     JNC    LATQ2        ; IF (NOT BOTTOM) GOTO LATQ2
  1103.     LXI    H,AT$QT        ; HL <-- QUEUE TOP ADDRESS
  1104. LATQ2    EQU    $
  1105.     SHLD    AT$QW        ; WRITE NEW POINTER
  1106.     LXI    H,AT$QS        ; HL <-- QUEUE SIZE POINTER
  1107.     INR    M        ; INCREMENT QUEUE SIZE
  1108.     RET
  1109. ;    Queue is empty and asynchronous transmitter is
  1110. ;    inactive.  Don't queue this entry, just send it out.
  1111. LATQ3    EQU    $
  1112.     SHLD    AT$BP        ; ESTABLISH NEW POINTER
  1113.     MVI    A,FEND        ; A <-- FEND
  1114.     OUT    THR        ; WRITE TRANSMIT HOLDING REGISTER
  1115.     MVI    A,4        ; NEW STATE (OPENING FRAME)
  1116.     STA    AT$STA        ; RECORD IT
  1117.     MVI    A,ERI+ETI+ELI+EMI ; 8250 INTERRUPT ENABLE FLAGS
  1118.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1119.     RET
  1120.     PAGE
  1121.  
  1122. ;    Buffer management routines
  1123.  
  1124. ;    Allocate a free cell
  1125. GCELL    EQU    $
  1126.     LHLD    FL$HC        ; HL <-- HEAD CELL ON FREE LIST
  1127.     MOV    A,H        ; MSB OF ADDRESS
  1128.     ORA    L        ; LSB OF ADDRESS
  1129.     JZ    GC$EL        ; IF (EMPTY LIST) GOTO GC$EL
  1130.     XCHG            ; DE <-- FREE CELL
  1131.     LXI    H,FL$HC        ; HL <-- HEAD CELL POINTER
  1132.     LDAX    D        ; A <-- LSB OF NEXT FREE CELL
  1133.     MOV    M,A        ; COPY TO FL$HC
  1134.     INX    D        ; ADVANCE POINTERS
  1135.     INX    H
  1136.     LDAX    D        ; A <-- MSB OF NEXT FREE CELL
  1137.     MOV    M,A        ; COPY TO FL$HC
  1138.     DCX    D        ; RESET FREE CELL POINTER
  1139. GC$EL    EQU    $
  1140.     RET
  1141.  
  1142. ;    Attach a cell to the free list
  1143. FCELL    EQU    $
  1144.     LXI    H,FL$HC        ; HL <-- HEAD CELL POINTER
  1145.     MOV    C,M        ; C <-- LSB OF FIRST CELL
  1146.     MOV    M,E        ; UPDATE LSB OF FL$HC
  1147.     INX    H        ; ADVANCE POINTER
  1148.     MOV    B,M        ; B <-- MSB OF FIRST CELL
  1149.     MOV    M,D        ; UPDATE MSB OF FL$HC
  1150.     XCHG            ; HL <-- RELEASED CELL
  1151.     MOV    E,M        ; E <-- LSB OF NEXT CELL
  1152.     MOV    M,C        ; COPY LSB OF OLD HC TO NEW
  1153.     INX    H        ; ADVANCE POINTER
  1154.     MOV    D,M        ; D <-- MSB OF NEXT CELL
  1155.     MOV    M,B        ; COPY MSB OF OLD HC TO NEW
  1156.     INX    H        ; ADVANCE POINTER
  1157.     MVI    M,0        ; RESET NBYTE
  1158.     INX    H
  1159.     MVI    M,0        ; RESET NREAD
  1160.     XCHG            ; HL <-- NEXT CELL IN CHAIN
  1161.     RET
  1162.  
  1163. ;    Attach a chain of cells to the free list
  1164. FCHN    EQU    $
  1165.     XCHG            ; DE <-- CELL TO BE RELEASED
  1166.     DI            ; GATE INTERRUPTS MOMENTARILY
  1167.     CALL    FCELL        ; FREE IT UP
  1168.     EI            ; UNGATE
  1169.     MOV    A,H        ; MSB OF FORWARD POINTER FROM CELL
  1170.     ORA    L        ; LSB OF SAME
  1171.     JNZ    FCHN        ; IF (MORE CELLS) GOTO FCHN
  1172.     RET
  1173.     PAGE
  1174.  
  1175. ;    Extract a character from the buffer referenced by HL
  1176. GCHAR    EQU    $
  1177.     PUSH    H        ; PRESERVE HL
  1178.     INX    H        ; SKIP FORWARD POINTER
  1179.     INX    H
  1180.     MOV    A,M        ; A <-- NBYTES
  1181.     INX    H        ; ADVANCE POINTER
  1182.     SUB    M        ; CHECK NREAD
  1183.     JZ    GC$BE        ; IF (BUFFER EXHAUSTED) GOTO GC$BE
  1184.     PUSH    D        ; PRESERVE DE
  1185.     INR    M        ; INCREMENT NREAD
  1186.     MOV    E,M        ; E <-- NREAD
  1187.     XRA    A
  1188.     MOV    D,A        ; EXTEND 16 BITS
  1189.     DAD    D        ; HL <-- HL + DE
  1190.     INR    A        ; RESET 'Z' FLAG
  1191.     MOV    A,M        ; A <-- CHARACTER
  1192.     POP    D        ; RESTORE DE
  1193.     POP    H        ; RESTORE HL
  1194.     RET
  1195. ;    Follow chain to next buffer
  1196. GC$BE    EQU    $
  1197.     POP    H        ; RESTORE HL
  1198.     PUSH    D        ; PRESERVE DE & BC
  1199.     PUSH    B
  1200.     XCHG            ; DE <-- BUFFER POINTER
  1201.     CALL    FCELL        ; RELEASE THIS CELL
  1202.     POP    B        ; RESTORE BC & DE
  1203.     POP    D
  1204.     MOV    A,H        ; MSB OF NEXT CELL IN CHAIN
  1205.     ORA    L        ; LSB OF SAME
  1206.     JNZ    GCHAR        ; IF (GOOD BUFFER) GOTO GCHAR
  1207.     RET            ; ELSE RETURN WITH 'Z' FLAG SET
  1208.  
  1209. ;    Stuff a character into the buffer referenced by HL
  1210. PCHAR    EQU    $
  1211.     PUSH    D        ; PRESERVE DE
  1212.     PUSH    PSW        ; PRESERVE PSW (CHARACTER)
  1213.     INX    H        ; SKIP FORWARD POINTER
  1214.     INX    H
  1215.     MVI    A,124        ; A <-- BUFFER LIMIT
  1216.     SUB    M        ; A <-- 124 - NBYTES
  1217.     CZ    PC$NB        ; IF (NEED BUFFER) CALL PC$NB
  1218.     PUSH    H        ; PRESERVE HL (BUFFER POINTER)
  1219.     INR    M        ; INCREMENT NBYTES
  1220.     MOV    E,M        ; E <-- NBYTES
  1221.     XRA    A
  1222.     MOV    D,A        ; EXTEND 16 BITS
  1223.     INX    H        ; SKIP NBYTES
  1224.     DAD    D        ; HL <-- HL + DE
  1225.     POP    D        ; RESTORE POINTER
  1226.     POP    PSW        ; RESTORE CHARACTER
  1227.     MOV    M,A        ; COPY CHARACTER TO BUFFER
  1228.     XCHG            ; HL <-- ORIGINAL POINTER
  1229.     DCX    H        ; ADJUST POINTER
  1230.     DCX    H
  1231.     POP    D        ; RESTORE DE
  1232.     XRA    A
  1233.     INR    A        ; RESET 'Z' FLAG
  1234.     RET
  1235. ;    Here if PCHAR needs a new buffer
  1236. PC$NB    EQU    $
  1237.     PUSH    H        ; PRESERVE HL
  1238.     CALL    GCELL        ; FREE CELL POINTER TO DE
  1239.     POP    H        ; RESTORE HL
  1240.     JZ    PC$BF        ; IF (BUFFERS FULL) GOTO PC$BF
  1241.     DCX    H
  1242.     MOV    M,D        ; COPY MSB TO PREVIOUS CELL
  1243.     DCX    H        ; ADVANCE POINTER
  1244.     MOV    M,E        ; COPY LSB TO PREVIOUS CELL
  1245.     XCHG            ; HL <-- NEW BUFFER POINTER
  1246.     MVI    M,0        ; RESET FORWARD POINTER
  1247.     INX    H        ; ADVANCE POINTER
  1248.     MVI    M,0
  1249.     INX    H
  1250.     RET
  1251. ;    Here if free cell not available
  1252. PC$BF    EQU    $
  1253.     POP    PSW        ; PURGE RETURN ADDRESS FROM STACK
  1254.     POP    PSW        ; RESTORE CHARACTER
  1255.     POP    D        ; RESTORE DE
  1256.     XRA    A        ; SET 'Z' FLAG
  1257.     RET
  1258.     PAGE
  1259.  
  1260. ;    Asynchronous Interrupt Response Code
  1261.  
  1262. AIRC    EQU    $
  1263.     PUSH    PSW        ; SAVE PROGRAM STATUS WORD
  1264.     IN    IIR        ; READ INTERRUPT IDENTIFICATION REG.
  1265.     RAR            ; RIGHT JUSTIFY ID BITS
  1266.     ANI    00000011B    ; MASK
  1267.     JZ    IRC$AM        ; IF (MODEM STATUS) GOTO IRC$AM
  1268.     DCR    A
  1269.     JZ    IRC$AT        ; IF (XMTR EMPTY) GOTO IRC$AT
  1270.     DCR    A
  1271.     JZ    IRC$AR        ; IF (DATA READY) GOTO IRC$AR
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277. ;    Here for line status interrupt
  1278. IRC$AL    EQU    $
  1279.     IN    LSR        ; READ LINE STATUS REGISTER
  1280.     ANI    BI        ; MASK BREAK INTERRUPT
  1281. ;    Treat overrun, parity, framing errors as data ready
  1282.     JZ    IRC$AR        ; IF (NOT BI) GOTO IRC$AR
  1283.     IN    RBR        ; FLUSH NULL FROM BUFFER
  1284.     POP    PSW        ; RESTORE PSW
  1285.     EI            ; UNGATE
  1286.     RET            ; RETURN FROM INTERRUPT
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292. ;    Here for modem status interrupt
  1293. IRC$AM    EQU    $
  1294.     IN    MSR        ; READ MODEM STATUS
  1295.     PUSH    PSW        ; SAVE STATUS
  1296.     ANI    DCTS+DDSR    ; MASK SOURCE BITS OF INTEREST
  1297.     RAR
  1298.     RAR
  1299.     JM    AM$1        ; IF (DELTA CTS) GOTO AM$1
  1300.     JC    INIT        ; IF (HOST LOST) GOTO INIT
  1301.  
  1302.     IF    TNCPLUS
  1303.     POP    PSW        ; Get status back from stack
  1304.     ANI    TERI        ; Ring indicate trailing edge?
  1305.     JZ    TICKX        ; No, go to return from interrupt
  1306.     LDA    TICKCNT        ; Increment tick count
  1307.     INR    A
  1308.     STA    TICKCNT
  1309. TICKX:    POP    PSW
  1310.     EI
  1311.     RET    
  1312.     ELSE
  1313. ;    Ignore other sources of this interrupt
  1314.     POP    PSW        ; REMOVE STATUS FROM STACK
  1315.     POP    PSW
  1316.     EI
  1317.     RET            ; RETURN FROM INTERRUPT
  1318.     ENDIF
  1319.  
  1320. ;    Here if Clear-To-Send has changed state
  1321. AM$1    EQU    $
  1322.     POP    PSW        ; FETCH MODEM STATUS FROM STACK
  1323.     ANI    TCTS        ; MASK TERMINAL CLEAR-TO-SEND STATUS
  1324.     JNZ    AM$2        ; IF (CLEAR-TO-SEND) GOTO AM$2
  1325. ;    Host has full buffer or something, stop sending
  1326.     MVI    A,ERI+ELI+EMI    ; INTERRUPT ENABLE FLAGS
  1327.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1328.     POP    PSW
  1329.     EI
  1330.     RET            ; RETURN FROM INTERRUPT
  1331. ;    Host is now ready to receive data again
  1332. AM$2    EQU    $
  1333.     LDA    AT$STA        ; A <-- STATE OF TRANSMITTER
  1334.     CPI    0FFH
  1335.     JZ    AM$3        ; IF (INACTIVE) GOTO AM$3
  1336.     MVI    A,ERI+ETI+ELI+EMI ; INTERRUPT ENABLE FLAGS
  1337.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1338. AM$3    EQU    $
  1339.     POP    PSW
  1340.     EI
  1341.     RET            ; RETURN FROM INTERRUPT
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347. ;    Here for asynchronous transmit interrupt
  1348. IRC$AT    EQU    $
  1349.     LDA    AT$STA        ; A <-- STATE OF TRANSMITTER
  1350.     ORA    A
  1351.     JZ    AT$S0        ; IF (NOT ESCAPED) GOTO AT$S0
  1352.     DCR    A
  1353.     JZ    AT$S1        ; IF (SENDING TFESC) GOTO AT$S1
  1354.     DCR    A
  1355.     JZ    AT$S2        ; IF (SENDING TFEND) GOTO AT$S2
  1356.     DCR    A
  1357.     JZ    AT$S3        ; IF (END OF FRAME) GOTO AT$S3
  1358.     DCR    A
  1359.     JZ    AT$S4        ; IF (OPENING FRAME) GOTO AT$S4
  1360.     JMP    RST1+1        ; IGNORE INACTIVE STATE
  1361.  
  1362.     IF    TNCPLUS
  1363. ;    ENTER HERE TO RETURN FROM AN INTERRUPT.  THE FIRST
  1364. ;    ITEM ON THE STACK WILL BE A RETURN ADDRESS TO THE
  1365. ;    RST INSTRUCTION WHICH GOT US HERE SO IT GETS WASTED.
  1366. ;    NEXT THE PROGRAM STATUS WORD (ACCUMULATOR & FLAGS)
  1367. ;    ARE RESTORE, INTERRUPTS ARE RE-ENABLED AND THE REST
  1368. ;    IS HISTORY.
  1369.  
  1370. RST1    EQU    $
  1371.     POP    PSW        ; PURGE BOGUS ADDRESS FROM STACK
  1372.     POP    PSW        ; RESTORE PROGRAM STATUS WORD
  1373.     EI            ; UNGATE INTERRUPTS
  1374.     RET            ; RETURN TO POINT OF INTERRUPT
  1375.     ENDIF
  1376.  
  1377. ;    Here for normal data transmission (not currently escaped)
  1378. AT$S0    EQU    $
  1379.     PUSH    H        ; PRESERVE HL
  1380.     LHLD    AT$BP        ; HL <-- BUFFER POINTER
  1381.     CALL    GCHAR        ; MOVE NEXT CHARACTER TO A
  1382.     SHLD    AT$BP        ; SAVE UPDATED POINTER
  1383.     POP    H        ; RESTORE HL
  1384.     JZ    AT$S0S3        ; IF (END OF FRAME) GOTO AT$S0S3
  1385.     CPI    FESC
  1386.     JZ    AT$S0S1        ; IF (CHAR = FESC) GOTO AT$S0S1
  1387.     CPI    FEND
  1388.     JZ    AT$S0S2        ; IF (CHAR = FEND) GOTO AT$S0S2
  1389.     OUT    THR        ; WRITE CHARACTER
  1390.     POP    PSW
  1391.     EI
  1392.     RET            ; RETURN FROM INTERRUPT
  1393. ;    Send FESC and change state to 1
  1394. AT$S0S1    EQU    $
  1395.     OUT    THR        ; WRITE FESC
  1396.     MVI    A,1        ; NEW STATE
  1397.     STA    AT$STA        ; RECORD NEW STATE
  1398.     POP    PSW
  1399.     EI
  1400.     RET            ; RETURN FROM INTERRUPT
  1401. ;    Send FESC and change state to 2
  1402. AT$S0S2    EQU    $
  1403.     MVI    A,FESC        ; A <-- FESC
  1404.     OUT    THR        ; WRITE
  1405.     MVI    A,2        ; NEW STATE
  1406.     STA    AT$STA        ; RECORD NEW STATE
  1407.     POP    PSW
  1408.     EI
  1409.     RET            ; RETURN FROM INTERRUPT
  1410. ;    Send FEND and change state to 3
  1411. AT$S0S3    EQU    $
  1412.     MVI    A,FEND        ; A <-- FEND
  1413.     OUT    THR        ; WRITE
  1414.     MVI    A,3        ; NEW STATE
  1415.     STA    AT$STA        ; RECORD NEW STATE
  1416.     POP    PSW
  1417.     EI
  1418.     RET            ; RETURN FROM INTERRUPT
  1419.  
  1420. ;    Send TFESC (FESC was last character sent)
  1421. AT$S1    EQU    $
  1422.     MVI    A,TFESC        ; A <-- TFESC
  1423.     OUT    THR        ; WRITE
  1424.     XRA    A        ; NEW STATE (NOT ESCAPED)
  1425.     STA    AT$STA        ; RECORD NEW STATE
  1426.     POP    PSW
  1427.     EI
  1428.     RET            ; RETURN FROM INTERRUPT
  1429.  
  1430. ;    Send TFEND (FESC was last character sent)
  1431. AT$S2    EQU    $
  1432.     MVI    A,TFEND        ; A <-- TFEND
  1433.     OUT    THR        ; WRITE
  1434.     XRA    A        ; NEW STATE (NOT ESCAPED)
  1435.     STA    AT$STA        ; RECORD NEW STATE
  1436.     POP    PSW
  1437.     EI
  1438.     RET            ; RETURN FROM INTERRUPT
  1439.  
  1440. ;    Here for end of frame transmission - FEND already sent
  1441. AT$S3    EQU    $
  1442.     MVI    A,ERI+ELI+EMI    ; RCVR, LINE, AND MODEM ENABLE FLAGS
  1443.     OUT    IER        ; WRITE INTERRUPT ENABLE REGISTER
  1444.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1445.     ORI    ATFC        ; SET ASYNC. XMTR FRAME COMPLETE
  1446.     STA    EA$FLG        ; WRITE FLAGS
  1447.     MVI    A,0FFH        ; NEW STATE (ASYNC. XMTR DISABLED)
  1448.     STA    AT$STA        ; RECORD IT
  1449.     POP    PSW
  1450.     EI
  1451.     RET
  1452.  
  1453. ;    Here for opening frame, send data frame control byte
  1454. AT$S4    EQU    $
  1455.     XRA    A        ; A <-- 0
  1456.     OUT    THR        ; WRITE CONTROL BYTE
  1457.     STA    AT$STA        ; ALSO IS OUR NEW STATE
  1458.     POP    PSW
  1459.     EI
  1460.     RET
  1461.  
  1462.  
  1463.  
  1464.  
  1465. ;    Here for asynchronous receive interrupt
  1466. IRC$AR    EQU    $
  1467.     LDA    AR$STA        ; A <-- STATE OF RECEIVER
  1468.     ORA    A
  1469.     JZ    AR$S0        ; IF (EXPECTING DATA) GOTO AR$S0
  1470.     DCR    A
  1471.     JZ    AR$S1        ; IF (ESCAPED) GOTO AR$S1
  1472.     DCR    A
  1473.     JZ    AR$S2        ; IF (EXPECTING COMMAND) GOTO AR$S2
  1474.     DCR    A
  1475.     JZ    AR$S3        ; IF (EXPECTING P-VALUE) GOTO AR$S3
  1476.     DCR    A
  1477.     JZ    AR$S4        ; IF (EXPECTING S-VALUE) GOTO AR$S4
  1478.     DCR    A
  1479.     JZ    AR$S5        ; IF (EXPECTING T-VALUE) GOTO AR$S5
  1480.     DCR    A
  1481.     JZ    AR$S6        ; IF (EXPECTING TXDELAY) GOTO AR$S6
  1482.  
  1483. ;    Here if waiting for FEND to begin a new frame
  1484. AR$S7    EQU    $
  1485.     IN    RBR        ; READ CHARACTER
  1486.     CPI    FEND
  1487.     JNZ    RST1+1        ; IF (NOT FEND) RETURN FROM INTERRUPT
  1488.     MVI    A,2        ; NEW STATE
  1489.     STA    AR$STA        ; RECORD NEW STATE
  1490.     POP    PSW
  1491.     EI
  1492.     RET            ; RETURN FROM INTERRUPT
  1493.  
  1494. ;    Here if expecting frame data
  1495. AR$S0    EQU    $
  1496.     IN    RBR        ; READ CHARACTER
  1497.     CPI    FESC
  1498.     JZ    AR$S0S1        ; IF (DATA = FESC) GOTO AR$S0S1
  1499.     CPI    FEND
  1500.     JZ    AR$S0S2        ; IF (DATA = FEND) GOTO AR$S0S2
  1501.     PUSH    H        ; PRESERVE HL
  1502.     LHLD    AR$BP        ; HL <-- BUFFER POINTER
  1503.     CALL    PCHAR        ; STORE CHARACTER
  1504.     JZ    AR$S0S7        ; IF (BUFFERS FULL) GOTO AR$S0A
  1505.     SHLD    AR$BP        ; RECORD NEW POINTER
  1506.     LHLD    AR$FSZ        ; HL <-- FRAME SIZE
  1507.     INX    H        ; INCREMENT COUNT
  1508.     SHLD    AR$FSZ        ; RECORD IT
  1509.     POP    H        ; RESTORE HL
  1510.     POP    PSW
  1511.     EI
  1512.     RET            ; RETURN FROM INTERRUPT
  1513. ;    Here we deal with a serious problem.  We are in the middle
  1514. ;    of a frame and filled our current buffer, but alas, there
  1515. ;    are no free cells to allocate.  Return all buffers in this
  1516. ;    frame to the free cell list and hope we recover.
  1517. AR$S0S7    EQU    $
  1518. AR$S1S7    EQU    $
  1519.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1520.     ORI    ARDD        ; ASYNC. RECEIVER DISCARDING DATA
  1521.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1522.     MVI    A,ADTR+OUT1    ; DTR & CD, NO RTS
  1523.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  1524.     POP    H        ; RESTORE HL
  1525. ;    Here we just change state to wait for the next incoming
  1526. ;    frame and hope by then that we have recovered some cells.
  1527. AR$S2S7    EQU    $
  1528.     MVI    A,7        ; NEW STATE
  1529.     STA    AR$STA        ; RECORD NEW STATE
  1530.     POP    PSW
  1531.     EI
  1532.     RET            ; RETURN FROM INTERRUPT
  1533. ;    FESC was just detected. Change state to 1 and see what follows.
  1534. AR$S0S1    EQU    $
  1535.     MVI    A,1        ; NEW STATE
  1536.     STA    AR$STA        ; RECORD IT
  1537.     POP    PSW
  1538.     EI
  1539.     RET            ; RETURN FROM INTERRUPT
  1540. ;    FEND was just detected.  Move frame to synch. transmit queue.
  1541. AR$S0S2    EQU    $
  1542.     PUSH    H        ; PRESERVE HL
  1543.     LHLD    AR$HC        ; HL <-- HEAD CELL POINTER
  1544.     SHLD    AR$FH        ; SAVE POINTER FOR EXEC
  1545.     LHLD    AR$FSZ        ; HL <-- FRAME SIZE
  1546.     SHLD    AR$FS        ; SAVE FOR EXECUTIVE
  1547.     MVI    A,2        ; NEW STATE
  1548.     STA    AR$STA        ; RECORD IT
  1549.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1550.     ORI    ARFC        ; ASYNC. RECEIVER FRAME COMPLETE
  1551.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1552.     MVI    A,ADTR+OUT1    ; DTR & CD, NO RTS
  1553.     OUT    MCR        ; WRITE MODEM CONTROL REGISTER
  1554.     POP    H        ; RESTORE HL
  1555.     POP    PSW
  1556.     EI
  1557.     RET            ; RETURN FROM INTERRUPT
  1558.  
  1559. ;    This character follows an FESC, must be TFESC or TFEND
  1560. AR$S1    EQU    $
  1561.     XRA    A        ; NEW STATE
  1562.     STA    AR$STA        ; RECORD IT
  1563.     IN    RBR        ; READ CHARACTER
  1564.     CPI    TFESC
  1565.     JZ    AR$S1A        ; IF (DATA = TFESC) GOTO AR$S1A
  1566.     CPI    TFEND
  1567.     JNZ    RST1+1        ; IF (DATA <> TFEND) RETURN FROM INT.
  1568. ;    Character was TFEND.  Translate it.
  1569.     MVI    A,FEND        ; A <-- FEND
  1570.     JMP    AR$S1B        ; STORE IT
  1571. ;    Character was TFESC.  Translate it.
  1572. AR$S1A    EQU    $
  1573.     MVI    A,FESC        ; A <-- FESC
  1574. AR$S1B    EQU    $
  1575.     PUSH    H        ; PRESERVE HL
  1576.     LHLD    AR$BP        ; HL <-- BUFFER POINTER
  1577.     CALL    PCHAR        ; STORE CHARACTER
  1578.     JZ    AR$S1S7        ; IF (BUFFERS FULL) GOTO AR$S1S7
  1579.     SHLD    AR$BP        ; RECORD NEW POINTER
  1580.     LHLD    AR$FSZ        ; HL <-- FRAME SIZE
  1581.     INX    H        ; INCREMENT COUNT
  1582.     SHLD    AR$FSZ        ; RECORD IT
  1583.     POP    H        ; RESTORE HL
  1584.     POP    PSW
  1585.     EI
  1586.     RET            ; RETURN FROM INTERRUPT
  1587.  
  1588. ;    Last character seen was FEND.  Look for frame command.
  1589. AR$S2    EQU    $
  1590.     IN    RBR        ; READ CHARACTER
  1591.     CPI    FEND
  1592.     JZ    RST1+1        ; RETURN FROM INTERRUPT
  1593.     ORA    A
  1594.     JZ    AR$S2S0        ; IF (DATA FRAME) GOTO AR$S2S0
  1595.     DCR    A
  1596.     JZ    AR$S2A        ; IF (R COMMAND) GOTO AR$S2A
  1597.     DCR    A
  1598.     JZ    AR$S2B        ; IF (P COMMAND) GOTO AR$S2B
  1599.     DCR    A
  1600.     JZ    AR$S2C        ; IF (S COMMAND) GOTO AR$S2C
  1601.     DCR    A
  1602.     JZ    AR$S2D        ; IF (T COMMAND) GOTO AR$S2D
  1603.     JMP    AR$S2S7        ; BOGUS COMMAND, WAIT FOR FEND
  1604. ;    Here if TxDelay value to follow
  1605. AR$S2A    EQU    $
  1606.     MVI    A,6        ; NEW STATE
  1607.     STA    AR$STA        ; RECORD IT
  1608.     POP    PSW
  1609.     EI
  1610.     RET            ; RETURN FROM INTERRUPT
  1611. ;    Here if Persistence value to follow
  1612. AR$S2B    EQU    $
  1613.     MVI    A,3
  1614.     STA    AR$STA    
  1615.     POP    PSW
  1616.     EI
  1617.     RET
  1618. ;    Here if Slot-time value to follow
  1619. AR$S2C    EQU    $
  1620.     MVI    A,4
  1621.     STA    AR$STA    
  1622.     POP    PSW
  1623.     EI
  1624.     RET
  1625. ;    Here if Squelch-delay value to follow
  1626. AR$S2D    EQU    $
  1627.     MVI    A,5
  1628.     STA    AR$STA    
  1629.     POP    PSW
  1630.     EI
  1631.     RET
  1632. ;    Here when data to follow
  1633. AR$S2S0    EQU    $
  1634.     PUSH    H        ; PRESERVE HL
  1635.     CALL    GCELL        ; GET A FREE CELL
  1636.     JZ    AR$S2S7        ; IF (BUFFERS FULL) GOTO AR$S0S7
  1637.     XCHG            ; HL <-- CELL POINTER
  1638.     SHLD    AR$BP        ; ESTABLISH NEW BUFFER POINTERS
  1639.     SHLD    AR$HC
  1640.     MVI    M,0        ; RESET FORWARD POINTER
  1641.     INX    H        ; ADVANCE POINTER
  1642.     MVI    M,0
  1643.     LXI    H,0        ; HL <-- 0
  1644.     SHLD    AR$FSZ        ; RESET FRAME SIZE
  1645.     POP    H        ; RESTORE HL
  1646.     XRA    A        ; NEW STATE
  1647.     STA    AR$STA        ; RECORD IT
  1648.     POP    PSW
  1649.     EI
  1650.     RET            ; RETURN FROM INTERRUPT
  1651.  
  1652. ;    Load a persistence value
  1653. AR$S3    EQU    $
  1654.     IN    RBR
  1655.     STA    PVAL
  1656.     MVI    A,2
  1657.     STA    AR$STA    
  1658.     POP    PSW
  1659.     EI
  1660.     RET
  1661.  
  1662. ;    Load a slot-time value
  1663. AR$S4    EQU    $
  1664.     IN    RBR
  1665.     STA    SVAL
  1666.     MVI    A,2
  1667.     STA    AR$STA    
  1668.     POP    PSW
  1669.     EI
  1670.     RET
  1671.  
  1672. ;    Load a squelch-delay value
  1673. AR$S5    EQU    $
  1674.     IN    RBR
  1675.     STA    TVAL
  1676.     MVI    A,2
  1677.     STA    AR$STA    
  1678.     POP    PSW
  1679.     EI
  1680.     RET
  1681.  
  1682. ;    Load a Tx relay delay value
  1683. AR$S6    EQU    $
  1684.     IN    RBR
  1685.     STA    RVAL
  1686.     MVI    A,2
  1687.     STA    AR$STA    
  1688.     POP    PSW
  1689.     EI
  1690.     RET
  1691.     PAGE
  1692.  
  1693. ;    Synchronous Transmitter Interrupt Response Code
  1694.  
  1695. STIRC   EQU     $
  1696.     PUSH    PSW             ; PRESERVE PROGRAM STATUS WORD
  1697.     PUSH    H               ; SAME WITH HL
  1698.     IN      STAT73          ; READ STATUS
  1699.     mov     a,l             ; save status
  1700.     ani     txintp          ; test tx interrupt bit
  1701.     jnz     stirc1          ; jump if interrupt appears normal
  1702. ; Here for an unexpected interrupt
  1703.     lhld    txicnt          ; fetch error counter
  1704.     inx     h               ; count this error
  1705.     shld    txicnt          ;
  1706.     push    d
  1707.     push    b
  1708.     call    init73          ; Re-initialise the 8273
  1709.     jmp     exit            ; Exit from the interrupt
  1710.  
  1711. ; Here for normal tx interrupt
  1712. stirc1: mov     a,l             ; Restore 8273 status
  1713.     ANI    TXIRA
  1714.     JNZ    ST$CI        ; IF (END-OF-FRAME) GOTO ST$CI
  1715. ;    Here if transmitter waiting for data
  1716.     LHLD    ST$BP        ; HL <-- BUFFER POINTER
  1717.     CALL    GCHAR        ; MOVE NEXT CHARACTER TO A
  1718.     OUT    TXDR73        ; WRITE CHARACTER
  1719.     SHLD    ST$BP        ; SAVE UPDATED POINTER
  1720.     POP    H        ; RESTORE HL
  1721.     POP     PSW
  1722.     EI
  1723.     RET                     ; RETURN FROM INTERRUPT
  1724.  
  1725. ;       Here for frame completion interrupt
  1726. ST$CI   EQU     $
  1727.     IN      TXIR73          ; READ RESULTS
  1728.     STA     ST$FR           ; SAVE RESULTS POINTER
  1729.     PUSH    D               ; PRESERVE DE
  1730.     LHLD    ST$BP           ; HL <-- CURRENT BUFFER POINTER
  1731.     XCHG                    ; MOVE POINTER TO DE
  1732.     CALL    FCELL           ; FREE THIS CELL
  1733.     POP     D               ; RESTORE DE
  1734.     LDA     EA$FLG          ; A <-- END ACTION FLAGS
  1735.     ORI     STFC            ; SYNC. TRANSMITTER FRAME COMPLETE
  1736.     STA     EA$FLG          ; SAVE UPDATED FLAGS
  1737.     POP     H               ; RESTORE HL
  1738.     POP     PSW
  1739.     EI
  1740.     RET                     ; RETURN FROM INTERRUPT
  1741.     PAGE
  1742.  
  1743. EXIT    pop     b               ; Restore registers
  1744.     pop     d               ;
  1745.     pop     h               ;
  1746.     pop     psw             ; Restore PSW
  1747.     ei                      ; Enable Interrupts
  1748.     ret                     ; Return to interrupted code
  1749.  
  1750.  
  1751. ;       Synchronous Receiver Interrupt Response Code
  1752.  
  1753. SRIRC   EQU     $
  1754.     PUSH    PSW             ; PRESERVE PROGRAM STATUS WORD
  1755.     LDA     SR$STA          ; A <-- STATE OF SYNC. RECEIVER
  1756.     ORA     A
  1757.     JNZ     SR$S1           ; IF (DISCARDING DATA) GOTO SR$S1
  1758.  
  1759. ;       Here if synchronous receiver state 0, recording data
  1760. SR$S0   EQU     $
  1761.     PUSH    H               ; PRESERVE HL
  1762.     IN      STAT73          ; READ STATUS
  1763.     mov     a,l             ; save status
  1764.     ani     rxintp          ; test rx interrupt bit
  1765.     jnz     sr$s01          ; jump if interrupt appears normal
  1766. ; Here for an unexpected interrupt
  1767.     lhld    rxicnt          ; fetch error counter
  1768.     inx     h               ; count this error
  1769.     shld    rxicnt          ;
  1770.     push    d
  1771.     push    b
  1772.     call    init73          ; Re-initialise the 8273
  1773.     jmp     exit            ; Exit from the interrupt
  1774.  
  1775. ; Here for normal rx interrupt
  1776. sr$s01: mov     a,l             ; Restore 8273 status
  1777.     ANI     RXIRA
  1778.     JNZ     SR$CI           ; IF (END-OF-FRAME) GOTO SR$CI
  1779. ;       Here if receiver has data to unload
  1780.     IN      RXDR73          ; READ CHARACTER
  1781.     LHLD    SR$BP           ; HL <-- BUFFER POINTER
  1782.     CALL    PCHAR           ; COPY CHARACTER TO BUFFER
  1783.     JZ      SR$BF           ; IF (BUFFERS FULL) GOTO SR$BF
  1784.     SHLD    SR$BP           ; SAVE UPDATED POINTER
  1785.     POP     H               ; RESTORE HL
  1786.     POP     PSW
  1787.     EI
  1788.     RET                     ; RETURN FROM INTERRUPT
  1789.  
  1790. ;       Here for frame completion interrupt
  1791. SR$CI   EQU     $
  1792.     IN      RXIR73          ; READ FRAME STATUS
  1793.     STA     SR$FR           ; SAVE IT FOR EXEC
  1794.     PUSH    B        ; PRESERVE BC
  1795.     MVI    B,20        ; TIMOUT
  1796.  
  1797. SR$CIA  EQU     $
  1798.     IN    STAT73        ; READ STATUS
  1799.     ANI    RINTP
  1800.     JZ    SR$CIB        ; IF (RESULTS COMPLETE) GOTO SR$CIB
  1801.     IN    STAT73        ; READ 8273 STATUS AGAIN
  1802.     ANI    RXIRA
  1803.     JNZ    SR$CIC        ; Go to read result
  1804.     DCR    B        ; Decrement timeout
  1805.     JNZ    SR$CIA        ; Continue testing
  1806.     CALL    INIT73
  1807.     POP     B
  1808.     POP    H
  1809.     POP    PSW
  1810.     EI
  1811.     RET
  1812.  
  1813. ;    Ready to read one byte of results code
  1814. SR$CIC: IN      RXIR73          ; READ RESULTS
  1815.     JMP    SR$CIA        ; WAIT FOR MORE, IF ANY
  1816. ;    Results are now complete
  1817. SR$CIB    EQU    $
  1818.     LDA     EA$FLG          ; A <-- END ACTION FLAGS
  1819.     ORI    SRFC        ; SYNC. RECEIVER FRAME COMPLETE
  1820.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1821.     POP    B        ; RESTORE BC
  1822.     POP    H        ; RESTORE HL
  1823.     POP    PSW
  1824.     EI
  1825.     RET            ; RETURN FROM INTERRUPT
  1826. ;    Again we must deal with being in the middle of a frame
  1827. ;    with no available free cells to continue.  Release the
  1828. ;       cells for this frame and cease reception till we recover.
  1829. SR$BF    EQU    $
  1830.     MVI    A,1        ; NEW STATE
  1831.     STA    SR$STA        ; RECORD IT
  1832.     LDA    EA$FLG        ; A <-- END ACTION FLAGS
  1833.     ORI     SRDD            ; SYNC. RECEIVER DISCARDING DATA
  1834.     STA    EA$FLG        ; SAVE UPDATED FLAGS
  1835.     POP     H               ; RESTORE HL
  1836.     POP    PSW
  1837.     EI
  1838.     RET            ; RETURN FROM INTERRUPT
  1839.  
  1840. ;       Here if synchronous receiver state 1, discarding data
  1841. SR$S1   EQU     $
  1842.     IN      STAT73          ; READ STATUS
  1843.     mov     a,l             ; save status
  1844.     ani     rxintp          ; test rx interrupt bit
  1845.     jnz     sr$s11          ; jump if interrupt appears normal
  1846. ; Here for an unexpected interrupt
  1847.     lhld    rxicnt          ; fetch error counter
  1848.     inx     h               ; count this error
  1849.     shld    rxicnt          ;
  1850.     push    d
  1851.     push    b
  1852.     call    init73          ; Re-initialise the 8273
  1853.     jmp     exit            ; Exit from the interrupt
  1854.  
  1855. ; Here for normal rx interrupt
  1856. sr$s11: mov     a,l             ; Restore 8273 status
  1857.     ANI     RXIRA
  1858.     JNZ     SR$DR           ; IF (END-OF-FRAME) GOTO SR$DR
  1859. ;       Here if receiver has data to unload
  1860.     IN      RXDR73          ; READ CHARACTER
  1861.     POP     PSW
  1862.     EI
  1863.     RET                     ; RETURN FROM INTERRUPT
  1864. ;       Here if discarding results
  1865. SR$DR   EQU     $
  1866.     IN      RXIR73          ; READ FRAME RESULTS
  1867.     PUSH    H
  1868.     PUSH    B               ; PRESERVE BC
  1869.     mvi     b,20            ; Timeout
  1870. SR$DRA  EQU     $
  1871.     IN      STAT73          ; READ STATUS
  1872.     ANI     RINTP
  1873.     JZ      SR$DRB          ; IF (RESULTS COMPLETE) GOTO SR$DRB
  1874.     IN      STAT73          ; Read 8273 status again
  1875.     ANI     RXIRA
  1876.     JNZ     SR$DRC
  1877.     DCR     B
  1878.     JNZ     SR$DRA          ; IF (NO RESULTS) GOTO SR$DRA
  1879.     CALL    INIT73
  1880.     POP     B
  1881.     POP     H
  1882.     POP     PSW
  1883.     EI
  1884.     RET
  1885.  
  1886. ;    Ready to read one byte of results code
  1887. SR$DRC:    IN    RXIR73        ; READ RESULTS
  1888.     JMP    SR$DRA        ; WAIT FOR MORE, IF ANY
  1889. ;    Results are now complete
  1890. SR$DRB    EQU    $
  1891.     POP    B        ; RESTORE BC
  1892.     POP    H
  1893.     POP    PSW
  1894.     EI
  1895.     RET            ; RETURN FROM INTERRUPT
  1896.     PAGE
  1897. **************************************************************************
  1898. RESET73:MVI    A,1    ; Reset 8273
  1899.     OUT    TEST73
  1900.     XCHG        ; Delay
  1901.     XCHG
  1902.     XRA    A
  1903.     OUT    TEST73    ; End of reset
  1904.     RET
  1905. **************************************************************************
  1906. INIT73:    CALL    RESET73
  1907. ;    Synchronous controller activation follows
  1908.     LXI    H,DTRANS
  1909.     CALL    SCMDOT        ; SET DATA XFER MODE
  1910.     LXI    H,OPMODE
  1911.     CALL    SCMDOT        ; SET OPERATING MODE
  1912.     LXI    H,SERIO
  1913.     CALL    SCMDOT        ; SET SERIAL I/O MODE
  1914.     LXI    H,SSDTR
  1915.     JMP    SCMDOT        ; SET SYNCH. DTR TO MODEM
  1916. ***************************************************************************
  1917.  
  1918. ;    Command and Immediate Results routines for 8273
  1919.  
  1920. SCMDOT:    EQU    $
  1921.     MOV    B,M        ; B <-- PARAMETER COUNT
  1922.     INX    H        ; ADVANCE TO COMMAND BYTE
  1923. CMD1    EQU    $
  1924.     IN    STAT73        ; READ STATUS
  1925.     RLC            ; MOVE CBSY INTO CARRY
  1926.     JC    CMD1        ; IF (CBSY <> 0) GOTO CMD1
  1927.     MOV    A,M        ; A <-- COMMAND BYTE
  1928.     OUT    CMND73        ; WRITE COMMAND
  1929. CMD2    EQU    $
  1930.     MOV    A,B        ; A <-- PARAMETER COUNT
  1931.     ANA    A
  1932.     RZ            ; IF (COUNT = 0) RETURN
  1933.     INX    H        ; ADVANCE POINTER
  1934.     DCR    B        ; DECREMENT PARAMETER COUNT
  1935. CMD3    EQU    $
  1936.     IN    STAT73        ; READ STATUS
  1937.     ANI    CPBF        ; MASK COMMAND PARAMETER BUFFER FULL
  1938.     JNZ    CMD3        ; IF (CPBF <> 0) GOTO CMD3
  1939.     MOV    A,M        ; A <-- PARAMETER
  1940.     OUT    PARM73        ; WRITE PARAMETER
  1941.     JMP    CMD2        ; CHECK FOR MORE PARAMETERS
  1942.  
  1943.  
  1944.  
  1945. SRSLIN    EQU    $
  1946.     IN    STAT73        ; READ STATUS
  1947.     ANI    CRBF        ; MASK COMMAND RESULTS BUFFER FULL
  1948.     JZ    SRSLIN        ; IF (CRBF = 0) GOTO SRSLIN
  1949.     IN    RESL73        ; READ RESULTS
  1950.     RET
  1951.     PAGE
  1952.  
  1953. ;    Messages
  1954.  
  1955. ;
  1956. ;    TNC's SIGNATURE
  1957. TNCID    EQU    $
  1958.     DB    'VADCG/ASHBY-2716 Terminal Node Controller'
  1959.     DB    CR,LF
  1960.     DB    'KISS Protocol Firmware Version 1.03   08 FEB 87'
  1961.     DB    CR,LF,LF
  1962.  
  1963. ;
  1964. ;    COMMAND SEQUENCES FOR 8273 CONTROLLER
  1965. DTRANS    DB    1,97H,1
  1966. OPMODE    DB    1,91H,03H
  1967. SERIO    DB    1,0A0H,1
  1968. SSDTR    DB    1,0A3H,4
  1969. STRTS    DB    1,0A3H,1
  1970. DARTS    DB    1,63H,0FEH
  1971. SRDIS    DB    0,0C5H
  1972. RPA    DB    0,22H
  1973.  
  1974.     END
  1975.  
  1976.